import { defineComponent, PropType, ref } from 'vue'
import initChart from '@/components/chart'
import type { Ref } from 'vue'
import {
  DataRelatedNode,
  DataRelatedNodeRelation
} from '@/service/modules/data-manage/types'
import TabsUtils from '@/store/tabs/tabs-util'
import { useRouter } from 'vue-router'

const props = {
  height: {
    type: [String, Number] as PropType<string | number>,
    default: 400
  },
  width: {
    type: [String, Number] as PropType<string | number>,
    default: '100%'
  },
  nodes: {
    type: Array as PropType<Array<DataRelatedNode>>,
    default: () => []
  },
  edges: {
    type: Array as PropType<Array<DataRelatedNodeRelation>>,
    default: () => []
  },
  labelShow: {
    type: Boolean as PropType<boolean>,
    default: true
  }
}

const GraphChart = defineComponent({
  name: 'GraphChart',
  props,
  setup(props) {
    const graphChartRef: Ref<HTMLDivElement | null> = ref(null)

    const option: any = {
      tooltip: {
        confine: true,
        formatter: (params: any) => {
          if (params.dataType === 'node') {
            const { datasourceName, dbName, tableName } = params.data

            return `
              ${window.$t('dataManage.datasourceName')}：${datasourceName}<br/>
              ${window.$t('dataManage.dbName')}：${dbName}<br/>
              ${window.$t('dataManage.table')}：${tableName}<br/>
            `
          } else if (params.dataType === 'edge') {
            const { taskName } = params.data
            return `
              ${window.$t('dataManage.relevanceTask')}：${taskName}<br/>
            `
          }
        }
      },
      series: [
        {
          type: 'graph',
          layout: 'force',
          draggable: true,
          force: {
            repulsion: 300,
            edgeLength: 150,
            gravity: 0.01
          },
          symbol: 'circle',
          symbolSize: 70,
          edgeSymbol: ['none', 'arrow'],
          roam: true,
          label: {
            show: props.labelShow,
            formatter: (val: any) => {
              let newStr = ''
              const str = val.data.tableName.split('')

              for (let i = 0, s; (s = str[i++]); ) {
                newStr += s
                if (!(i % 10)) newStr += '\n'
              }

              return newStr.length > 50 ? newStr.slice(0, 50) + '...' : newStr
            }
          },
          nodes: props.nodes.map((item) => {
            const category = item.depth
            const itemStyle = {
              color: ''
            }
            switch (category) {
              case 0:
                itemStyle.color = '#66CC1D'
                break
              case 1:
                itemStyle.color = '#1DCCA3'
                break
              case 2:
                itemStyle.color = '#1D4CCC'
                break
              case 3:
                itemStyle.color = '#DE1424'
                break
            }

            return {
              name: item.name,
              datasourceId: item.datasourceId,
              datasourceName: item.datasourceName,
              dbName: item.dbName,
              tableName: item.tableName,
              category,
              itemStyle
            }
          }),
          edges: props.edges.map((item) => {
            return {
              source: item.startNode,
              target: item.endNode,
              taskName: item.taskName
            }
          }),
          lineStyle: {
            opacity: 0.9,
            width: 2,
            curveness: 0
          }
        }
      ]
    }
    const router = useRouter()
    const nodeDblClickHandler = (params: any) => {
      //打开节点对应表的数据血缘标签
      if (params.data) {
        router.push({
          path: '/dataManage/dataCatalog/tableManage/dataRelateds',
          query: {
            tab:
              window.$t('dataManage.table') +
              `:${params.data.tableName}` +
              window.$t('dataManage.related'),
            tabName: 'DataRelatedTab',
            datasourceId: params.data.datasourceId,
            dbName: params.data.dbName,
            tableName: params.data.tableName
          }
        })
      }
    }
    initChart(graphChartRef, option, undefined, nodeDblClickHandler)
    return { graphChartRef }
  },
  render() {
    const { height, width } = this
    return (
      <div
        ref='graphChartRef'
        style={{
          height: typeof height === 'number' ? height + 'px' : height,
          width: typeof width === 'number' ? width + 'px' : width
        }}
      />
    )
  }
})

export default GraphChart
